package com.alibaba.citrus.cr.mn.order.center.forecastorder.ability;

import com.alibaba.acm.shaded.com.google.common.collect.Lists;
import com.alibaba.citrus.cr.common.enums.ordercenter.DictionaryTypeEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.ForecastOrderTypeEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.OrderCategoryEnum;
import com.alibaba.citrus.cr.common.exception.FunctionException;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.*;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.dataobject.request.LogisticWarehouseQueryRequest;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.dataobject.request.ShipToPartyByAccurateQueryRequest;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.dataobject.request.SoldToPartyByAccurateQueryRequest;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.dataobject.request.*;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.dataobject.response.*;
import com.alibaba.citrus.cr.mn.order.center.facade.function.check.CommonCheck;
import com.alibaba.citrus.cr.mn.order.center.facade.function.convert.ForecastOrderBOToPriceOrderInfoConvertor;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.item.normal.scitem.model.openapi.ResultWrapper;
import com.alibaba.cz.item.normal.scitem.model.openapi.scitem.ConvertCoefficientInfo;
import com.alibaba.cz.item.normal.scitem.model.openapi.scitem.SpecConvertCoefficientRequest;
import com.alibaba.cz.item.normal.scitem.model.openapi.scitem.SpecConvertCoefficientResponse;
import com.alibaba.cz.item.normal.scitem.openapi.IScItemSpecQueryService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.crforecastsales.bo.ForecastOrderBO;
import com.epoch.app.crforecastsales.bo.ForecastOrderLineBO;
import com.epoch.app.crforecastsales.enums.ForecastStatusEnum;
import com.epoch.app.crforecastsales.sdo.ForecastOrderLineSDO;
import com.epoch.app.crforecastsales.sdo.ForecastOrderSDO;
import com.epoch.app.crpricecenter.dto.request.ActivityInfoRequest;
import com.epoch.app.crpricecenter.dto.request.ActivityItemInfoRequest;
import com.epoch.app.crpricecenter.dto.response.ActivityInfoResponse;
import com.epoch.app.crpricecenter.model.dto.ActivityResponse;
import com.epoch.app.mnordercenter.model.dto.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.*;

/**
 * @author dongju.fyj
 * @version 1.0
 * @date 2023/12/18
 */
@Component
public class ForecastOrderBatchCreateAbility {

    private static final Log log = Log.getLogger(ForecastOrderBatchCreateAbility.class);

    @Resource
    private BusinessChannelAbilityAdapter businessChannelAbilityAdapter;
    @Resource
    private ShipToPartyAbilityAdapter shipToPartyAbilityAdapter;
    @Resource
    private SoldToPartyAbilityAdapter soldToPartyAbilityAdapter;
    @DubboReference
    private IScItemSpecQueryService scItemSpecQueryService;
    @Resource
    private CargoZoneAdapter cargoZoneAdapter;
    @Resource
    private ItemQueryAdapter itemQueryAdapter;
    @Resource
    private NormalPriceQueryUtils normalPriceQueryUtils;
    @Resource
    private CommonCheck commonCheck;
    @Resource
    private BaseDataServiceAdapter baseDataServiceAdapter;
    @Resource
    private SalesOrgAbilityAdapter salesOrgAbilityAdapter;
    @Resource
    private CustomerCenterAdapter customerCenterAdapter;

    public void enrichDefaultValue(ForecastOrderBO forecastOrderBO, ForecastOrderSDO forecastOrderSDO) {
        log.info("修改接口预报单状态:{}", String.valueOf(forecastOrderSDO.getStatus()));
        switch (ForecastStatusEnum.of(forecastOrderSDO.getStatus())) {
            case DRAFT:
            case WAITING_FOR_REPLY:
                enrichDraftOrWaitingForReplyValue(forecastOrderBO, forecastOrderSDO);
                break;
            case PARTIAL_REPLY:
            case COMPLETED:
                enrichPartialReplyValue(forecastOrderBO, forecastOrderSDO);
                break;
            default:
                throw new FunctionException("OC-01-001-01-16-048");
        }
    }

    private void enrichPartialReplyValue(ForecastOrderBO forecastOrderBO, ForecastOrderSDO forecastOrderSDO) {
        Date customerExpectTDate = forecastOrderSDO.getCustomerExpectTDate();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        forecastOrderBO.setCustomerExpectTDate(simpleDateFormat.format(customerExpectTDate));
        forecastOrderBO.setShipToPartyCode(forecastOrderSDO.getReceiveAddressCode());
        forecastOrderBO.setProductGroupCode(forecastOrderSDO.getProductGroupCode());
        forecastOrderBO.setCustomerPurchaseOrderNo(forecastOrderSDO.getCustomerPurchaseOrderNo());
        Date customerPurchaseDate = forecastOrderSDO.getCustomerPurchaseDate();
        if (customerPurchaseDate != null) {
            forecastOrderBO.setCustomerPurchaseDate(simpleDateFormat.format(customerPurchaseDate));
        }
        forecastOrderBO.setVaildBeginTime(forecastOrderSDO.getVaildBeginTime());
        forecastOrderBO.setSalesOrganizationCode(forecastOrderSDO.getSalesOrganizationCode());
        forecastOrderBO.setOrderTypeCode(forecastOrderSDO.getOrderTypeCode());
        forecastOrderBO.setSoldToPartyCode(forecastOrderSDO.getCustomerCode());
        forecastOrderBO.setChannelCode(forecastOrderSDO.getChannelCode());
        forecastOrderBO.setSalesChannelCode(forecastOrderSDO.getSalesChannelCode());
        forecastOrderBO.setSalesDepartmentCode(forecastOrderSDO.getSalesDepartmentCode());
        forecastOrderBO.setTransportModeCode(forecastOrderSDO.getTransportModeCode());
        forecastOrderBO.setTransportModeName(forecastOrderSDO.getTransportModeName());
        forecastOrderBO.setModifierCode(forecastOrderSDO.getModifierCode());
        forecastOrderBO.setCreateReasonCode(forecastOrderSDO.getCreateReason());
        forecastOrderBO.setCreateReasonCode(forecastOrderSDO.getCreateReason());
        forecastOrderBO.setRemark(forecastOrderSDO.getRemark());
        forecastOrderBO.setShippingWarehouseId(forecastOrderSDO.getShippingWarehouseId());
        forecastOrderBO.setShippingWarehouseCode(forecastOrderSDO.getShippingWarehouseCode());
        forecastOrderBO.setShippingWarehouseName(forecastOrderSDO.getShippingWarehouseName());

        forecastOrderBO.setFulfillmentTypeCode(forecastOrderSDO.getFulfillmentTypeCode());
        forecastOrderBO.setFulfillmentPriority(forecastOrderSDO.getFulfillmentPriority());
        forecastOrderBO.setAutoFulfillment(forecastOrderSDO.getAutoFulfillment());
        forecastOrderBO.setOrderTag(forecastOrderSDO.getOrderTag());
        if (!ForecastStatusEnum.COMPLETED.getNumValue().equals(forecastOrderSDO.getStatus())) {
            // 完成状态不用db数据回填，支持蒙维斯修改回告状态
            forecastOrderBO.setBizFeatures(forecastOrderSDO.getBizFeatures());
        }

        Map<String, ForecastOrderLineSDO> existLineMap = forecastOrderSDO.getForecastOrderLineSDOList().stream().collect(toMap(ForecastOrderLineSDO::getSerialNumber, p -> p, (v1, v2) -> v1));
        forecastOrderBO.getForecastOrderLineBOList().forEach(o -> {
            if (StringUtils.isNotBlank(o.getLineNum())) {
                ForecastOrderLineSDO forecastOrderLineSDO = existLineMap.get(o.getLineNum());
                if (Objects.isNull(forecastOrderLineSDO)) {
                    throw new FunctionException("OC-01-001-01-16-017", "");
                }
                switch (ForecastStatusEnum.of(forecastOrderLineSDO.getStatus())) {
                    case WAITING_FOR_REPLY:
                        // 待回复
                        break;
                    case PARTIAL_REPLY:
                        // 部分回复
                        if (StringUtils.isNotBlank(o.getQuantity())) {
                            int compareTo = new BigDecimal(o.getQuantity()).compareTo(BigDecimal.valueOf(forecastOrderLineSDO.getActualTotalReplyAmount()));
                            if (compareTo < 0) {
                                //预报数量 < 已回复数量 修改错误信息
                                throw new FunctionException("OC-04-003-01-16-026");
                            }
                            if (compareTo == 0) {
                                o.setStatus(ForecastStatusEnum.COMPLETED.getNumValue());
                            }
                        }
                        break;
                    case COMPLETED:
                    case CANCELLED:
                        // 已完成/已取消
                        break;
                    default:
                        throw new FunctionException("OC-01-001-01-16-048");
                        // break;
                }
                // 【发货仓编码】与【工厂+库存地点】二选一必填，后面取仓库信息
                o.setShippingWarehouseCode(forecastOrderLineSDO.getShippingWarehouseCode());
                o.setDeliveryFactoryCode(forecastOrderLineSDO.getDeliveryFactoryCode());
                o.setStockCode(forecastOrderLineSDO.getStockCode());
                // 物料编码不允许修改,若传入则校验与原明细行数据是否一致
                if (StringUtils.isNotBlank(o.getProductCode()) && !o.getProductCode().equals(forecastOrderLineSDO.getScItemOutCode())) {
                    throw new FunctionException("OC-04-003-01-16-025", "物料编码");
                }
                o.setProductCode(forecastOrderLineSDO.getScItemOutCode());
                o.setSaleUnitCode(forecastOrderLineSDO.getSaleUnitCode());
                if (StringUtils.isBlank(o.getQuantity())) {
                    o.setQuantity(forecastOrderLineSDO.getQuantity());
                }
                o.setActivityCode(forecastOrderLineSDO.getActivityCode());
                o.setActivityNumber(forecastOrderLineSDO.getActivityNumber());
                o.setDetailRemark(forecastOrderLineSDO.getDetailRemark());

                o.setSourceLineNum(forecastOrderLineSDO.getSourceLineNum());
                o.setGoodsProductationTime(forecastOrderLineSDO.getGoodsProductationTime());
                o.setSourceUnit(forecastOrderLineSDO.getSourceUnit());
                o.setSourceQuantity(forecastOrderLineSDO.getSourceQuantity());
                o.setSourcePrice(forecastOrderLineSDO.getSourcePrice());
                o.setActivityCode(forecastOrderLineSDO.getActivityCode());
                o.setActivityName(forecastOrderLineSDO.getActivityName());
                o.setDetailRemark(forecastOrderLineSDO.getDetailRemark());
                if (!ForecastStatusEnum.COMPLETED.getNumValue().equals(forecastOrderLineSDO.getStatus())) {
                    // 完成状态不用db数据回填，支持蒙维斯修改回告状态
                    o.setBizFeatures(forecastOrderLineSDO.getBizFeatures());
                }
            }
        });
        log.info("forecastOrderBO部分回复:{}", JSON.toJSONString(forecastOrderBO));
    }

    private void enrichDraftOrWaitingForReplyValue(ForecastOrderBO forecastOrderBO, ForecastOrderSDO forecastOrderSDO) {
        if (StringUtils.isBlank(forecastOrderBO.getCustomerExpectTDate())) {
            Date customerExpectTDate = forecastOrderSDO.getCustomerExpectTDate();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            forecastOrderBO.setCustomerExpectTDate(simpleDateFormat.format(customerExpectTDate));
        }
        if (StringUtils.isBlank(forecastOrderBO.getShipToPartyCode())) {
            forecastOrderBO.setShipToPartyCode(forecastOrderSDO.getReceiveAddressCode());
        }
        if (StringUtils.isBlank(forecastOrderBO.getProductGroupCode())) {
            forecastOrderBO.setProductGroupCode(forecastOrderSDO.getProductGroupCode());
        }
        if (StringUtils.isBlank(forecastOrderBO.getCustomerPurchaseDate())) {
            Date customerPurchaseDate = forecastOrderSDO.getCustomerPurchaseDate();
            if (Objects.nonNull(customerPurchaseDate)) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                forecastOrderBO.setCustomerPurchaseDate(simpleDateFormat.format(customerPurchaseDate));
            }
        }
        if (forecastOrderBO.getVaildBeginTime() == null) {
            Date vaildBeginTime = forecastOrderSDO.getVaildBeginTime();
            if (Objects.nonNull(vaildBeginTime)) {
                forecastOrderBO.setVaildBeginTime(vaildBeginTime);
            }
        }
        if (StringUtils.isBlank(forecastOrderBO.getSalesOrganizationCode())) {
            forecastOrderBO.setSalesOrganizationCode(forecastOrderSDO.getSalesOrganizationCode());
        }
        if (StringUtils.isBlank(forecastOrderBO.getOrderTypeCode())) {
            forecastOrderBO.setOrderTypeCode(forecastOrderSDO.getOrderTypeCode());
        }
        if (StringUtils.isBlank(forecastOrderBO.getSoldToPartyCode())) {
            forecastOrderBO.setSoldToPartyCode(forecastOrderSDO.getCustomerCode());
        }
        if (StringUtils.isBlank(forecastOrderBO.getChannelCode())) {
            forecastOrderBO.setChannelCode(forecastOrderSDO.getChannelCode());
        }
        if (StringUtils.isBlank(forecastOrderBO.getSalesChannelCode())) {
            forecastOrderBO.setSalesChannelCode(forecastOrderSDO.getSalesChannelCode());
        }
        if (StringUtils.isBlank(forecastOrderBO.getSalesDepartmentCode())) {
            forecastOrderBO.setSalesDepartmentCode(forecastOrderSDO.getSalesDepartmentCode());
        }
        if (StringUtils.isBlank(forecastOrderBO.getTransportModeCode())) {
            forecastOrderBO.setTransportModeCode(forecastOrderSDO.getTransportModeCode());
        }
        if (StringUtils.isBlank(forecastOrderBO.getShippingWarehouseId())) {
            forecastOrderBO.setShippingWarehouseId(forecastOrderSDO.getShippingWarehouseId());
        }
        if (StringUtils.isBlank(forecastOrderBO.getShippingWarehouseCode())) {
            forecastOrderBO.setShippingWarehouseCode(forecastOrderSDO.getShippingWarehouseCode());
        }
        if (StringUtils.isBlank(forecastOrderBO.getShippingWarehouseName())) {
            forecastOrderBO.setShippingWarehouseName(forecastOrderSDO.getShippingWarehouseName());
        }
        if (StringUtils.isBlank(forecastOrderBO.getOrderType())) {
            forecastOrderBO.setOrderType(forecastOrderSDO.getOrderType());
        }
        // 支持应用端清空内容
        forecastOrderBO.setCustomerPurchaseOrderNo(forecastOrderSDO.getCustomerPurchaseOrderNo());
        forecastOrderBO.setCreateReasonCode(forecastOrderSDO.getCreateReason());
        forecastOrderBO.setRemark(forecastOrderSDO.getRemark());

        if (CollectionUtils.isNotEmpty(forecastOrderBO.getForecastOrderLineBOList())) {
            Map<String, ForecastOrderLineSDO> existLineMap = forecastOrderSDO.getForecastOrderLineSDOList().stream().collect(toMap(ForecastOrderLineSDO::getSerialNumber, p -> p, (v1, v2) -> v1));
            forecastOrderBO.getForecastOrderLineBOList().forEach(o -> {
                if (StringUtils.isNotBlank(o.getLineNum())) {
                    ForecastOrderLineSDO forecastOrderLineSDO = existLineMap.get(o.getLineNum());
                    if (Objects.isNull(forecastOrderLineSDO)) {
                        throw new FunctionException("OC-01-001-01-16-017", "");
                    }
                    // 回填发货工厂、发货仓库、库存地点
                    if (StringUtils.isBlank(o.getShippingWarehouseCode()) && (StringUtils.isNotBlank(o.getDeliveryFactoryCode()) || StringUtils.isNotBlank(o.getStockCode()))) {
                        // 不回填
                    } else if (StringUtils.isNotBlank(o.getShippingWarehouseCode()) && StringUtils.isBlank(o.getDeliveryFactoryCode()) && StringUtils.isBlank(o.getStockCode())) {
                        // 不回填
                    } else {
                        if (StringUtils.isBlank(o.getShippingWarehouseCode())) {
                            o.setShippingWarehouseCode(forecastOrderLineSDO.getShippingWarehouseCode());
                        }
                        if (StringUtils.isBlank(o.getDeliveryFactoryCode())) {
                            o.setDeliveryFactoryCode(forecastOrderLineSDO.getDeliveryFactoryCode());
                        }
                        if (StringUtils.isBlank(o.getStockCode())) {
                            o.setStockCode(forecastOrderLineSDO.getStockCode());
                        }
                    }
                    // 物料编码不允许修改,若传入则校验与原明细行数据是否一致
                    if (StringUtils.isNotBlank(o.getProductCode()) && !o.getProductCode().equals(forecastOrderLineSDO.getScItemOutCode())) {
                        throw new FunctionException("OC-04-003-01-16-025", "物料编码");
                    }
                    if (StringUtils.isBlank(o.getProductCode())) {
                        o.setProductCode(forecastOrderLineSDO.getScItemOutCode());
                    }
                    if (StringUtils.isBlank(o.getSaleUnitCode())) {
                        o.setSaleUnitCode(forecastOrderLineSDO.getSaleUnitCode());
                    }
                    if (StringUtils.isBlank(o.getQuantity())) {
                        o.setQuantity(forecastOrderLineSDO.getQuantity());
                    }
                    if (StringUtils.isBlank(o.getActivityCode())) {
                        o.setActivityCode(forecastOrderLineSDO.getActivityCode());
                    }
                    if (StringUtils.isBlank(o.getActivityNumber())) {
                        o.setActivityNumber(forecastOrderLineSDO.getActivityNumber());
                    }
                    if (StringUtils.isBlank(o.getGoodsProductationTime())) {
                        o.setGoodsProductationTime(forecastOrderLineSDO.getGoodsProductationTime());
                    }
                    if (StringUtils.isBlank(o.getSourceUnit())) {
                        o.setSourceUnit(forecastOrderLineSDO.getSourceUnit());
                    }
                    if (Objects.isNull(o.getSourcePrice())) {
                        o.setSourcePrice(forecastOrderLineSDO.getSourcePrice());
                    }
                    if (Objects.isNull(o.getSourceQuantity())) {
                        o.setSourceQuantity(forecastOrderLineSDO.getSourceQuantity());
                    }
                    // 更改了单位则不赋值，后面重新查询计算
                    if (StringUtils.isBlank(o.getSaleUnitCode()) || o.getSaleUnitCode().equals(forecastOrderLineSDO.getSaleUnitCode())) {
                        if (Objects.isNull(o.getUnitPrice())) {
                            o.setUnitPrice(forecastOrderLineSDO.getUnitPrice());
                        }
                    }

                    // 支持应用端清空内容
                    o.setDetailRemark(forecastOrderLineSDO.getDetailRemark());
                }
            });
        } else {
            List<ForecastOrderLineBO> forecastOrderLineBOS = JSONObject.parseArray(JSONObject.toJSONString(forecastOrderSDO.getForecastOrderLineSDOList()), ForecastOrderLineBO.class);
            forecastOrderBO.setForecastOrderLineBOList(forecastOrderLineBOS);
        }
        log.info("forecastOrderBO待回复参数:{}", JSON.toJSONString(forecastOrderBO));
    }

    public void invalidMainData(List<ForecastOrderBO> forecastOrderBOS, List<CreateForecastResponseDTO> createResponseList, String taskId) {
        //创建人查询
        List<String> creatorCodes = forecastOrderBOS.stream().map(ForecastOrderBO::getCreatorCode).distinct().collect(toList());
        Map<String, Modifiers> creatorMap = commonCheck.getModifiers(creatorCodes);

        //修改人查询
        List<String> modifierCodes = forecastOrderBOS.stream().map(ForecastOrderBO::getModifierCode).distinct().collect(toList());
        Map<String, Modifiers> modifierMap = commonCheck.getModifiers(modifierCodes);

        //业务单元查询
        Map<String, DictionaryResponse> businessUnitMap = new HashMap<>();
        List<DictionaryResponse> businessUnitList = baseDataServiceAdapter.queryDictionarys(DictionaryTypeEnum.BUSINESS_UNIT_CODE.getCode());
        if (CollectionUtils.isNotEmpty(businessUnitList)) {
            businessUnitMap = businessUnitList.stream().collect(Collectors.toMap(DictionaryResponse::getCode, Function.identity()));
        }

        //销售组织
        List<String> salesOrgCodeList = forecastOrderBOS.stream()
                .map(ForecastOrderBO::getSalesOrganizationCode)
                .filter(StringUtils::isNotBlank).distinct()
                .collect(Collectors.toList());
        Map<String, String> salesOrgMap = customerCenterAdapter.querySalesOrganization(salesOrgCodeList);
        log.info("ForecastOrderBatchCreateAbility#invalidMainData salesOrgMap={}", JSON.toJSONString(salesOrgMap));

        //销售渠道
        List<String> salesChannelCodeList = forecastOrderBOS.stream()
                .map(ForecastOrderBO::getSalesChannelCode)
                .filter(StringUtils::isNotBlank).distinct()
                .collect(Collectors.toList());
        Map<String, String> salesChannelMap = customerCenterAdapter.querySalesChannel(salesChannelCodeList);
        log.info("ForecastOrderBatchCreateAbility#invalidMainData salesChannelMap={}", JSON.toJSONString(salesChannelMap));

        //业务渠道
        List<String> channelCodes = forecastOrderBOS.stream().map(ForecastOrderBO::getChannelCode).distinct().collect(toList());
        List<BusinessChannelDTO> businessChannelList = businessChannelAbilityAdapter.queryBusinessChannel(channelCodes);
        Map<String, BusinessChannelDTO> businessChannelMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(businessChannelList)) {
            businessChannelMap = businessChannelList.stream().collect(toMap(BusinessChannelDTO::getChannelCode, Function.identity(), (v1, v2) -> v1));
        }

        //根据收货仓信息查询送达方
        Map<String, LogisticWarehouseQueryDTO> requestRecordMap = new HashMap<>();
        for (ForecastOrderBO forecastOrderBO : forecastOrderBOS) {
            boolean receiveWarehouseCodeIsBlank = StringUtils.isBlank(forecastOrderBO.getReceiveWarehouseCode());
            boolean receiveFactoryOrStockIsBlank = StringUtils.isBlank(forecastOrderBO.getReceiveFactoryCode()) || StringUtils.isBlank(forecastOrderBO.getReceiveStockCode());
            if (!receiveWarehouseCodeIsBlank) {
                //收货逻辑仓库编码不为空时，不查询收货仓信息
                continue;
            }

            if (receiveFactoryOrStockIsBlank) {
                //收货工厂编码或收货库存编码其一为空时，不查询收货仓信息
                continue;
            }

            //检查缓存是否有数据，减少查询频次
            String receiveWarehouseKey = String.format("%s%s%s", forecastOrderBO.getReceiveWarehouseCode(), forecastOrderBO.getReceiveFactoryCode(), forecastOrderBO.getReceiveStockCode());
            if (requestRecordMap.containsKey(receiveWarehouseKey)) {
                LogisticWarehouseQueryDTO cargoZoneSDO = requestRecordMap.get(receiveWarehouseKey);
                if (Objects.nonNull(cargoZoneSDO) && StringUtils.isNotBlank(cargoZoneSDO.getCode())) {
                    forecastOrderBO.setReceiveWarehouseCode(cargoZoneSDO.getCode());
                }
                continue;
            }

            //构造查询仓库接口入参
            LogisticWarehouseQueryRequest queryCargoZoneByParamRequest = new LogisticWarehouseQueryRequest();
            queryCargoZoneByParamRequest.setLogicWarehouseCode(forecastOrderBO.getReceiveWarehouseCode());
            queryCargoZoneByParamRequest.setFactoryCode(forecastOrderBO.getReceiveFactoryCode());
            queryCargoZoneByParamRequest.setStorageLocation(forecastOrderBO.getReceiveStockCode());

            List<LogisticWarehouseQueryDTO> receiveWarehouseList = cargoZoneAdapter.queryCargoZoneListByParam(Lists.newArrayList(queryCargoZoneByParamRequest));
            if (CollectionUtils.isEmpty(receiveWarehouseList)) {
                requestRecordMap.put(receiveWarehouseKey, null);
                continue;
            }
            LogisticWarehouseQueryDTO cargoZoneSDO = receiveWarehouseList.get(0);
            if (Objects.nonNull(cargoZoneSDO) && StringUtils.isNotBlank(cargoZoneSDO.getCode())) {
                forecastOrderBO.setReceiveWarehouseCode(cargoZoneSDO.getCode());
            }

            //缓存查询结果，减少查询频次
            requestRecordMap.put(receiveWarehouseKey, cargoZoneSDO);
        }

        //货品组
        ItemGroupAbilityRequest listRequest = new ItemGroupAbilityRequest();
        listRequest.setLimit(999);
        List<ItemGroupAbilityDTO> listResponse = itemQueryAdapter.queryScItemGroup(listRequest);
        Map<String, ItemGroupAbilityDTO> productGroupMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(listResponse)) {
            productGroupMap = listResponse.stream().collect(Collectors.toMap(ItemGroupAbilityDTO::getProductGroupCode, p -> p, (v1, v2) -> v1));
        }

        //送达方
        Map<String, ItemGroupAbilityDTO> finalProductGroupMap = productGroupMap;
        List<ShipToPartyByAccurateQueryRequest> shipToPartyReqList = forecastOrderBOS.stream()
                .map(o -> {
                    if (!finalProductGroupMap.containsKey(o.getProductGroupCode())) {
                        return null;
                    }

                    ShipToPartyByAccurateQueryRequest req = new ShipToPartyByAccurateQueryRequest();
                    req.setBusinessType(o.getProductGroupCode());
                    req.setSalesChannelCode(o.getChannelCode());
                    req.setSalesOrganizationCode(o.getSalesOrganizationCode());
                    req.setShipToPartyCode(o.getShipToPartyCode());
                    req.setSoldToPartyCode(o.getSoldToPartyCode());
                    return req;
                })
                .filter(Objects::nonNull)
                .distinct()
                .collect(collectingAndThen(toCollection(() -> new TreeSet<>(Comparator.comparing(o ->
                        String.format("%s_%s_%s_%s_%s",
                                o.getBusinessType(),
                                o.getShipToPartyCode(),
                                o.getSoldToPartyCode(),
                                o.getSalesChannelCode(),
                                o.getSalesOrganizationCode())
                ))), ArrayList::new));
        Map<String, ShipToPartyByAccurateQueryDTO> shipPartyMap = new HashMap<>();
        List<ShipToPartyByAccurateQueryDTO> shipResult = shipToPartyAbilityAdapter.queryShipToPartyByAccurate(shipToPartyReqList);
        if (CollectionUtils.isNotEmpty(shipResult)) {
            shipPartyMap = shipResult.stream().collect(toMap(o ->
                            String.format("%s_%s_%s_%s_%s",
                                    o.getBusinessType(),
                                    o.getSalesOrganizationCode(),
                                    o.getSalesChannelCode(),
                                    o.getShipToPartyCode(),
                                    o.getSoldToPartyCode()),
                    Function.identity(), (v1, v2) -> v1));
        }
        log.info("ForecastOrderBatchCreateAbility#invalidMainData shipPartyMap:{}", JSON.toJSONString(shipPartyMap));

        //售达方
        List<SoldToPartyByAccurateQueryRequest> soldToPartyReqList = forecastOrderBOS.stream()
                .map(o -> {
                    if (!finalProductGroupMap.containsKey(o.getProductGroupCode())) {
                        return null;
                    }

                    SoldToPartyByAccurateQueryRequest req = new SoldToPartyByAccurateQueryRequest();
                    req.setBusinessType(o.getProductGroupCode());
                    req.setSalesChannelCode(o.getChannelCode());
                    req.setSalesOrganizationCode(o.getSalesOrganizationCode());
                    req.setSoldToPartyCode(o.getSoldToPartyCode());
                    return req;
                })
                .filter(Objects::nonNull)
                .distinct()
                .collect(collectingAndThen(toCollection(() -> new TreeSet<>(Comparator.comparing(o ->
                        String.format("%s_%s_%s_%s",
                                o.getBusinessType(),
                                o.getSoldToPartyCode(),
                                o.getSalesChannelCode(),
                                o.getSalesOrganizationCode())
                ))), ArrayList::new));
        Map<String, SoldToPartyByAccurateQueryDTO> soldPartyMap = new HashMap<>();
        List<SoldToPartyByAccurateQueryDTO> soldResult = soldToPartyAbilityAdapter.querySoldToPartyByAccurate(soldToPartyReqList);
        if (CollectionUtils.isNotEmpty(soldResult)) {
            soldPartyMap = soldResult.stream().collect(toMap(o ->
                            String.format("%s_%s_%s_%s",
                                    o.getBusinessType(),
                                    o.getSalesOrganizationCode(),
                                    o.getSalesChannelCode(),
                                    o.getSoldToPartyCode()),
                    Function.identity(), (v1, v2) -> v1));
        }
        log.info("ForecastOrderBatchCreateAbility#invalidMainData soldPartyMap:{}", JSON.toJSONString(soldPartyMap));

        //活动查询
        log.info("ForecastOrderBatchCreateAbility#invalidMainData#activity forecastOrderBOS:{}", JSON.toJSONString(forecastOrderBOS));
        List<ActivityInfoRequest> activityInfoRequestList = forecastOrderBOS.stream()
                .filter(o -> o.getOrderTypeCode().equals(ForecastOrderTypeEnum.REPLENISH_FORECAST.getCode()))
                .map(o -> {
                    ActivityInfoRequest req = new ActivityInfoRequest();
                    req.setClientId(o.getSoldToPartyCode());
                    req.setActivityUseTime(new Date());
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    Date parse = null;
                    try {
                        parse = simpleDateFormat.parse(o.getCustomerExpectTDate());
                    } catch (ParseException e) {
                        log.error("解析期望交货日期异常", e);
                    }
                    req.setDeliveryDate(parse);
                    List<ActivityItemInfoRequest> itemList = o.getForecastOrderLineBOList().stream().map(x -> {
                        ActivityItemInfoRequest activityItemInfoRequest = new ActivityItemInfoRequest();
                        activityItemInfoRequest.setItemId(x.getProductCode());
                        activityItemInfoRequest.setItemQuantity(Long.parseLong(x.getQuantity()));
                        return activityItemInfoRequest;
                    }).collect(toList());
                    req.setItemList(itemList);
                    req.setSalesOrganization(o.getSalesOrganizationCode());
                    req.setBusinessChannel(o.getChannelCode());
                    req.setOrderType(o.getOrderType());
                    req.setShipAddressId(o.getShipToPartyCode());
                    String mainOrderId = String.format("%s_%s_%s_%s_%s", req.getClientId(), req.getSalesOrganization(), req.getBusinessChannel(), req.getOrderType(), req.getShipAddressId());
                    req.setMainOrderId(mainOrderId);
                    return req;
                }).distinct()
                .collect(collectingAndThen(toCollection(() -> new TreeSet<>(Comparator.comparing(ActivityInfoRequest::getMainOrderId))), ArrayList::new));
        Result<ActivityResponse> activityResponseResult = normalPriceQueryUtils.queryActivity(activityInfoRequestList);
        Map<String, List<ActivityInfoResponse>> activityMap = new HashMap<>();
        if (Objects.nonNull(activityResponseResult) && Objects.nonNull(activityResponseResult.getResult())
                && CollectionUtils.isNotEmpty(activityResponseResult.getResult().getActivityInfoResponseList())) {
            activityMap = activityResponseResult.getResult().getActivityInfoResponseList().stream().collect(groupingBy(ActivityInfoResponse::getMainOrderId));
        }
        log.info("ForecastOrderBatchCreateAbility#invalidMainData#activity activityMap:{}", JSON.toJSONString(activityMap));

        //发货仓
        List<LogisticWarehouseQueryRequest> shippingCargoList = new ArrayList<>();
        for (ForecastOrderBO forecastOrderBO : forecastOrderBOS) {
            shippingCargoList.addAll(forecastOrderBO.getForecastOrderLineBOList().stream()
                    .map(o -> {
                        LogisticWarehouseQueryRequest req = new LogisticWarehouseQueryRequest();
                        if (StringUtils.isNotBlank(o.getShippingWarehouseCode())) {
                            req.setLogicWarehouseCode(o.getShippingWarehouseCode());
                        } else {
                            req.setFactoryCode(o.getDeliveryFactoryCode());
                            req.setStorageLocation(o.getStockCode());
                        }
                        return req;
                    }).distinct()
                    .collect(collectingAndThen(toCollection(() -> new TreeSet<>(Comparator.comparing(o ->
                            String.format("%s_%s_%s", o.getLogicWarehouseCode(), o.getFactoryCode(), o.getStorageLocation())
                    ))), ArrayList::new)));
        }
        List<LogisticWarehouseQueryDTO> shippingResult = cargoZoneAdapter.queryCargoZoneListByParam(shippingCargoList);
        Map<String, LogisticWarehouseQueryDTO> cargoZoneMap = new HashMap<>();
        Map<String, LogisticWarehouseQueryDTO> codeCargoZoneMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(shippingResult)) {
            cargoZoneMap = shippingResult.stream().collect(toMap(o -> o.getSapFactoryCode() + "-" + o.getWarehouseCode(), Function.identity(), (v1, v2) -> v1));
            codeCargoZoneMap = shippingResult.stream().collect(toMap(LogisticWarehouseQueryDTO::getCode, Function.identity(), (v1, v2) -> v1));
        }

        //收货仓
        List<LogisticWarehouseQueryRequest> receiveCargoList = forecastOrderBOS.stream()
                .filter(o -> {
                    boolean receiveWarehouseCodeIsBlank = StringUtils.isBlank(o.getReceiveWarehouseCode());
                    boolean receiveFactoryOrStockIsBlank = StringUtils.isBlank(o.getReceiveFactoryCode()) || StringUtils.isBlank(o.getReceiveStockCode());
                    //收货逻辑仓库编码不为空 或 收货工厂编码或收货库存编码不为空时 查询收货仓信息
                    return !receiveWarehouseCodeIsBlank || !receiveFactoryOrStockIsBlank;
                })
                .map(o -> {
                    LogisticWarehouseQueryRequest req = new LogisticWarehouseQueryRequest();
                    req.setLogicWarehouseCode(o.getReceiveWarehouseCode());
                    req.setFactoryCode(o.getReceiveFactoryCode());
                    req.setStorageLocation(o.getReceiveStockCode());
                    return req;
                }).distinct()
                .collect(collectingAndThen(toCollection(() -> new TreeSet<>(Comparator.comparing(o ->
                        String.format("%s_%s_%s", o.getLogicWarehouseCode(), o.getFactoryCode(), o.getStorageLocation())
                ))), ArrayList::new));
        Map<String, LogisticWarehouseQueryDTO> receiveCargoZoneMap = new HashMap<>();
        Map<String, LogisticWarehouseQueryDTO> receiveCodeCargoZoneMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(receiveCargoList)) {
            List<LogisticWarehouseQueryDTO> receiveResult = cargoZoneAdapter.queryCargoZoneListByParam(receiveCargoList);
            if (CollectionUtils.isNotEmpty(receiveResult)) {
                receiveCargoZoneMap = receiveResult.stream().collect(toMap(o -> o.getSapFactoryCode() + "-" + o.getWarehouseCode(), Function.identity(), (v1, v2) -> v1));
                receiveCodeCargoZoneMap = receiveResult.stream().collect(toMap(LogisticWarehouseQueryDTO::getCode, Function.identity(), (v1, v2) -> v1));
            }
        }

        //货品有效性校验
        List<String> productCodes = new ArrayList<>();
        forecastOrderBOS.stream()
                .map(ForecastOrderBO::getForecastOrderLineBOList)
                .forEach(o -> productCodes.addAll(o.stream().map(ForecastOrderLineBO::getProductCode).collect(toList())));
        List<String> distinctProductCodes = productCodes.stream().distinct().collect(toList());

        ItemSearchAbilityRequest itemSearchAbilityRequest = new ItemSearchAbilityRequest();
        itemSearchAbilityRequest.setProductCodes(distinctProductCodes);
        List<ItemSearchAbilityDTO> itemResultList = itemQueryAdapter.queryItem(itemSearchAbilityRequest);
        Map<String, ItemSearchAbilityDTO> scItemSDOMap = new HashMap<>();
        if (Objects.nonNull(itemResultList)) {
            scItemSDOMap = itemResultList.stream().collect(toMap(ItemSearchAbilityDTO::getOuterId, Function.identity(), (v1, v2) -> v1));
        }

        //单位库
        ItemUnitAbilityRequest scItemUnitAbilityRequest = new ItemUnitAbilityRequest();
        scItemUnitAbilityRequest.setSize(999);
//        listRequest.setLimit(999);
        List<ItemUnitAbilityDTO> unitList = itemQueryAdapter.queryScItemUnitMap(scItemUnitAbilityRequest);
        Map<String, ItemUnitAbilityDTO> itemUnitMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(unitList)) {
            itemUnitMap = unitList.stream().collect(Collectors.toMap(ItemUnitAbilityDTO::getUnitCode, p -> p, (v1, v2) -> v1));
        }

        //单位转换关系
        SpecConvertCoefficientRequest specConvertRequest = new SpecConvertCoefficientRequest();
        specConvertRequest.setMaterialCodeList(distinctProductCodes);
        log.info("单位转换关系入参：" + JSON.toJSONString(specConvertRequest));
        ResultWrapper<List<SpecConvertCoefficientResponse>> unitConvertResult = scItemSpecQueryService.getConvertCoefficientForInner(specConvertRequest);
        log.info("单位转换关系结果：" + JSON.toJSONString(unitConvertResult));
        Map<String, Integer> unitConvertMap = new HashMap<>();
        if (Objects.nonNull(unitConvertResult) && CollectionUtils.isNotEmpty(unitConvertResult.getResult())) {
            Map<String, List<ConvertCoefficientInfo>> collect = unitConvertResult.getResult().stream().collect(toMap(SpecConvertCoefficientResponse::getMaterialCode, SpecConvertCoefficientResponse::getConvertCoefficientInfos, (v1, v2) -> v1));
            for (Map.Entry<String, List<ConvertCoefficientInfo>> entry : collect.entrySet()) {
                String productCode = entry.getKey();
                unitConvertMap.putAll(entry.getValue().stream().collect(toMap(o -> productCode + "-" + o.getUnitCode(), ConvertCoefficientInfo::getConvertCoefficient, (v1, v2) -> v1)));
            }
        }
        log.info("unitConvertMap结果:{}", JSON.toJSONString(unitConvertMap));

        //主单循环校验
        Iterator<ForecastOrderBO> orderSDOIterator = forecastOrderBOS.iterator();
        while (orderSDOIterator.hasNext()) {
            ForecastOrderBO forecastOrderBO = orderSDOIterator.next();
            log.info("ForecastOrderBatchCreateAbility#invalidMainData forecastOrderBO={}", JSON.toJSONString(forecastOrderBO));

            CreateForecastResponseDTO forecastResponseDTO = new CreateForecastResponseDTO();
            forecastResponseDTO.setSourceOrderNo(forecastOrderBO.getSourceOrderNo());
            forecastResponseDTO.setSuccess(Boolean.FALSE);
            forecastResponseDTO.setReqNo(forecastOrderBO.getReqNo());
            forecastResponseDTO.setBatchTaskId(taskId);

            //货品组校验
            if (!productGroupMap.containsKey(forecastOrderBO.getProductGroupCode())) {
                forecastResponseDTO.setErrorCode("OC-01-001-01-16-036");
                forecastResponseDTO.setMessage("产品组编码/名称不存在");
                createResponseList.add(forecastResponseDTO);
                orderSDOIterator.remove();
                continue;
            }
            ItemGroupAbilityDTO productGroup = productGroupMap.get(forecastOrderBO.getProductGroupCode());
            forecastOrderBO.setProductGroupCode(productGroup.getProductGroupCode());
            forecastOrderBO.setProductGroupName(productGroup.getProductGroupName());

            //创建人校验
            if (Objects.nonNull(forecastOrderBO.getCreatorCode())) {
                if (!creatorMap.containsKey(forecastOrderBO.getCreatorCode())) {
                    forecastResponseDTO.setErrorCode("OC-01-001-01-16-041");
                    forecastResponseDTO.setMessage("人员不存在");
                    createResponseList.add(forecastResponseDTO);
                    orderSDOIterator.remove();
                    continue;
                }
                Modifiers creator = creatorMap.get(forecastOrderBO.getCreatorCode());
                if (creator.getStatus() != 1) {
                    forecastResponseDTO.setErrorCode("OC-01-001-01-16-041");
                    forecastResponseDTO.setMessage("人员不存在");
                    createResponseList.add(forecastResponseDTO);
                    orderSDOIterator.remove();
                    continue;
                }
                forecastOrderBO.setCreatorId(creator.getId());
                forecastOrderBO.setCreatorCode(creator.getWorkId());
                forecastOrderBO.setCreatorName(creator.getName());
            }

            //修改人校验
            if (Objects.nonNull(forecastOrderBO.getModifierCode())) {
                if (!modifierMap.containsKey(forecastOrderBO.getModifierCode())) {
                    forecastResponseDTO.setErrorCode("OC-01-001-01-16-041");
                    forecastResponseDTO.setMessage("人员不存在");
                    createResponseList.add(forecastResponseDTO);
                    orderSDOIterator.remove();
                    continue;
                }
                Modifiers modifiers = modifierMap.get(forecastOrderBO.getModifierCode());
                if (modifiers.getStatus() != 1) {
                    forecastResponseDTO.setErrorCode("OC-01-001-01-16-041");
                    forecastResponseDTO.setMessage("人员不存在");
                    createResponseList.add(forecastResponseDTO);
                    orderSDOIterator.remove();
                    continue;
                }
                forecastOrderBO.setModifierId(modifiers.getId());
                forecastOrderBO.setModifierCode(modifiers.getWorkId());
                forecastOrderBO.setModifierName(modifiers.getName());
            }

            //销售单元校验
            if (!businessUnitMap.containsKey(forecastOrderBO.getBusinessUnitCode())) {
                forecastResponseDTO.setErrorCode("OC-04-001-01-16-003");
                forecastResponseDTO.setMessage("业务单元编码不存在");
                createResponseList.add(forecastResponseDTO);
                orderSDOIterator.remove();
                continue;
            }
            DictionaryResponse dictionaryResponse = businessUnitMap.get(forecastOrderBO.getBusinessUnitCode());
            forecastOrderBO.setBusinessUnitName(dictionaryResponse.getName());
            forecastOrderBO.setBisUnitCode(dictionaryResponse.getId());

            //销售组织校验
            if (!salesOrgMap.containsKey(forecastOrderBO.getSalesOrganizationCode())) {
                forecastResponseDTO.setErrorCode("OC-04-001-01-16-003");
                forecastResponseDTO.setMessage("销售组织编码/名称不存在");
                createResponseList.add(forecastResponseDTO);
                orderSDOIterator.remove();
                continue;
            }
//            SalesBizOrgQueryDTO salesOrganization = salesOrgMap.get(forecastOrderBO.getProductGroupCode() + "-" + forecastOrderBO.getSalesOrganizationCode());
//            forecastOrderBO.setSalesOrganizationId(String.valueOf(salesOrganization.getId()));
            forecastOrderBO.setSalesOrganizationCode(forecastOrderBO.getSalesOrganizationCode());
            forecastOrderBO.setSalesOrganizationName(salesOrgMap.get(forecastOrderBO.getSalesOrganizationCode()));

            //业务渠道校验
            if (!businessChannelMap.containsKey(forecastOrderBO.getChannelCode())) {
                forecastResponseDTO.setErrorCode("OC-01-001-01-16-051");
                forecastResponseDTO.setMessage("业务渠道不存在");
                createResponseList.add(forecastResponseDTO);
                orderSDOIterator.remove();
                continue;
            }
            BusinessChannelDTO businessChannel = businessChannelMap.get(forecastOrderBO.getChannelCode());
            if (!Objects.equals(businessChannel.getStatus(), "1")) {
                forecastResponseDTO.setErrorCode("OC-04-001-01-16-026");
                forecastResponseDTO.setMessage("业务渠道已禁用");
                createResponseList.add(forecastResponseDTO);
                orderSDOIterator.remove();
                continue;
            }
            forecastOrderBO.setChannelCode(businessChannel.getChannelCode());
            forecastOrderBO.setChannelName(businessChannel.getChannelName());

            //售达方校验
            String soldToPartyKey = String.format("%s_%s_%s_%s",
                    forecastOrderBO.getProductGroupCode(),
                    forecastOrderBO.getSalesOrganizationCode(),
                    forecastOrderBO.getChannelCode(),
                    forecastOrderBO.getSoldToPartyCode());
            log.info("soldToPartyKey参数:{}", soldToPartyKey);
            if (!soldPartyMap.containsKey(soldToPartyKey)) {
                forecastResponseDTO.setErrorCode("OC-01-001-01-16-032");
                forecastResponseDTO.setMessage("售达方编码/名称不存在");
                createResponseList.add(forecastResponseDTO);
                orderSDOIterator.remove();
                continue;
            }
            SoldToPartyByAccurateQueryDTO soldToParty = soldPartyMap.get(soldToPartyKey);
            forecastOrderBO.setSoldToPartyCode(soldToParty.getSoldToPartyCode());
            forecastOrderBO.setSoldToPartyName(soldToParty.getSoldToPartyName());

            //送达方校验
            if (StringUtils.isNotBlank(forecastOrderBO.getShipToPartyCode())) {
                String shipToPartyKey = String.format("%s_%s_%s_%s_%s",
                        forecastOrderBO.getProductGroupCode(),
                        forecastOrderBO.getSalesOrganizationCode(),
                        forecastOrderBO.getChannelCode(),
                        forecastOrderBO.getShipToPartyCode(),
                        forecastOrderBO.getSoldToPartyCode());
                if (!shipPartyMap.containsKey(shipToPartyKey)) {
                    forecastResponseDTO.setErrorCode("OC-01-001-01-16-033");
                    forecastResponseDTO.setMessage("送达方编码/名称不存在");
                    createResponseList.add(forecastResponseDTO);
                    orderSDOIterator.remove();
                    continue;
                }
                ShipToPartyByAccurateQueryDTO shipToParty = shipPartyMap.get(shipToPartyKey);
                forecastOrderBO.setShipToPartyCode(shipToParty.getShipToPartyCode());
                forecastOrderBO.setShipToPartyName(shipToParty.getShipToPartyName());

                JSONObject bizFeatures = JSON.parseObject(StringUtils.isBlank(forecastOrderBO.getBizFeatures()) ? "{}" : forecastOrderBO.getBizFeatures());
                if (StringUtils.isBlank(bizFeatures.getString("contract"))) {
                    bizFeatures.put("contract", shipToParty.getConsigneeName());
                }
                if (StringUtils.isBlank(bizFeatures.getString("contractPhone"))) {
                    bizFeatures.put("contractPhone", shipToParty.getConsigneePhone());
                }
                if (StringUtils.isBlank(bizFeatures.getString("addressName"))) {
                    bizFeatures.put("addressName", shipToParty.getReceivingAddress());
                }
                forecastOrderBO.setBizFeatures(bizFeatures.toJSONString());


                if (OrderCategoryEnum.GROUP.getCode().equals(forecastOrderBO.getOrderCategoryCode())) {
                    // 集团销售预报订单，若未传入，根据【产品组+业务渠道+销售组织+售达方+送达方】查询客户中心送达方档案，获取销售部门编码、名称、销售组编码、名称后保存
                    if (StringUtils.isBlank(forecastOrderBO.getSalesChannelCode()) && StringUtils.isBlank(forecastOrderBO.getSalesChannelName())
                            && StringUtils.isBlank(forecastOrderBO.getSalesDepartmentCode()) && StringUtils.isBlank(forecastOrderBO.getSalesDepartmentName())) {
                        forecastOrderBO.setSalesChannelCode(shipToParty.getOuterSalesDepartmentCode()); // 销售办公室
                        forecastOrderBO.setSalesChannelName(shipToParty.getOuterSalesDepartment());
                        forecastOrderBO.setSalesDepartmentCode(shipToParty.getOuterSalesGroupCode()); // 销售组
                        forecastOrderBO.setSalesDepartmentName(shipToParty.getOuterSalesGroup());
                    }
                }
            } else {
                //送达方根据收货仓库信息未查询到时，报收货仓库不存在
                forecastResponseDTO.setErrorCode("OC-01-001-01-16-010");
                forecastResponseDTO.setMessage("收货仓库不存在");
                createResponseList.add(forecastResponseDTO);
                orderSDOIterator.remove();
                continue;
            }

            //收货仓校验
            LogisticWarehouseQueryDTO receiveCargoZoneSDO = null;
            if (StringUtils.isNotBlank(forecastOrderBO.getReceiveWarehouseCode())) {
                String cargoKey = forecastOrderBO.getReceiveWarehouseCode();
                if (!receiveCodeCargoZoneMap.containsKey(cargoKey)) {
                    forecastResponseDTO.setErrorCode("OC-01-001-01-16-010");
                    forecastResponseDTO.setMessage("收货仓库不存在");
                    createResponseList.add(forecastResponseDTO);
                    orderSDOIterator.remove();
                    continue;
                }
                receiveCargoZoneSDO = receiveCodeCargoZoneMap.get(cargoKey);

                if (receiveCargoZoneSDO.getStatus() != 1) {
                    forecastResponseDTO.setErrorCode("OC-04-001-01-16-029");
                    forecastResponseDTO.setMessage("收货仓库已禁用");
                    createResponseList.add(forecastResponseDTO);
                    orderSDOIterator.remove();
                    continue;
                }
            } else if (StringUtils.isNotBlank(forecastOrderBO.getReceiveFactoryCode()) && StringUtils.isNotBlank(forecastOrderBO.getReceiveStockCode())) {
                String cargoKey = forecastOrderBO.getReceiveFactoryCode() + "-" + forecastOrderBO.getReceiveStockCode();
                if (!receiveCargoZoneMap.containsKey(cargoKey)) {
                    forecastResponseDTO.setErrorCode("OC-01-001-01-16-010");
                    forecastResponseDTO.setMessage("收货仓库不存在");
                    createResponseList.add(forecastResponseDTO);
                    orderSDOIterator.remove();
                    continue;
                }
                receiveCargoZoneSDO = receiveCargoZoneMap.get(cargoKey);
                if (receiveCargoZoneSDO.getStatus() != 1) {
                    forecastResponseDTO.setErrorCode("OC-04-001-01-16-029");
                    forecastResponseDTO.setMessage("收货仓库已禁用");
                    createResponseList.add(forecastResponseDTO);
                    orderSDOIterator.remove();
                    continue;
                }
            }
            if (Objects.nonNull(receiveCargoZoneSDO)) {
                forecastOrderBO.setReceiveWarehouseCode(receiveCargoZoneSDO.getCode());
                forecastOrderBO.setReceiveWarehouseName(receiveCargoZoneSDO.getName());
                forecastOrderBO.setReceiveFactoryCode(receiveCargoZoneSDO.getSapFactoryCode());
                forecastOrderBO.setReceiveStockCode(receiveCargoZoneSDO.getWarehouseCode());
            }
            // 销售渠道编码校验
            if (StringUtils.isNotBlank(forecastOrderBO.getSalesChannelCode()) && salesChannelMap.containsKey(forecastOrderBO.getSalesChannelCode())) {
                if (!OrderCategoryEnum.GROUP.getCode().equals(forecastOrderBO.getOrderCategoryCode())) {
                    forecastOrderBO.setSalesChannelName(salesChannelMap.get(forecastOrderBO.getSalesChannelCode()));
                }
            }

            //明细校验
            List<ForecastOrderLineBO> forecastOrderLineBOList = forecastOrderBO.getForecastOrderLineBOList();
            detailLoopOuter:
            {
                for (ForecastOrderLineBO forecastOrderLineBO : forecastOrderLineBOList) {
                    //发货仓校验 0112 以子单的纬度校验仓
                    LogisticWarehouseQueryDTO cargoZoneSDO = null;
                    log.info("forecastOrderLineBO结果:{}", JSON.toJSONString(forecastOrderLineBO));
                    if (StringUtils.isNotBlank(forecastOrderLineBO.getShippingWarehouseCode())) {
                        String cargoKey = forecastOrderLineBO.getShippingWarehouseCode();
                        if (!codeCargoZoneMap.containsKey(cargoKey)) {
                            forecastResponseDTO.setErrorCode("OC-04-001-01-16-015");
                            forecastResponseDTO.setMessage("发货仓库不存在");
                            createResponseList.add(forecastResponseDTO);
                            orderSDOIterator.remove();
                            continue;
                        }
                        cargoZoneSDO = codeCargoZoneMap.get(cargoKey);

                        if (cargoZoneSDO.getStatus() != 1) {
                            forecastResponseDTO.setErrorCode("OC-04-001-01-16-027");
                            forecastResponseDTO.setMessage("发货仓库已禁用");
                            createResponseList.add(forecastResponseDTO);
                            orderSDOIterator.remove();
                            continue;
                        }
                    } else {
                        String cargoKey = forecastOrderLineBO.getDeliveryFactoryCode() + "-" + forecastOrderLineBO.getStockCode();
                        if (!cargoZoneMap.containsKey(cargoKey)) {
                            forecastResponseDTO.setErrorCode("OC-04-001-01-16-015");
                            forecastResponseDTO.setMessage("发货仓库不存在");
                            createResponseList.add(forecastResponseDTO);
                            orderSDOIterator.remove();
                            continue;
                        }
                        cargoZoneSDO = cargoZoneMap.get(cargoKey);
                        if (cargoZoneSDO.getStatus() != 1) {
                            forecastResponseDTO.setErrorCode("OC-04-001-01-16-027");
                            forecastResponseDTO.setMessage("发货仓库已禁用");
                            createResponseList.add(forecastResponseDTO);
                            orderSDOIterator.remove();
                            continue;
                        }
                    }
                    forecastOrderBO.setShippingWarehouseCode(cargoZoneSDO.getCode());
                    forecastOrderBO.setShippingWarehouseName(cargoZoneSDO.getName());
                    forecastOrderBO.setShippingWarehouseId(cargoZoneSDO.getId());
                    forecastOrderBO.setDeliveryFactoryCode(cargoZoneSDO.getSapFactoryCode());
                    forecastOrderBO.setStockCode(cargoZoneSDO.getWarehouseCode());

                    // 仓库信息下沉 0112 支持多仓，填充发货仓库名称，发货工厂编码，库存地点编码
                    forecastOrderLineBO.setShippingWarehouseCode(cargoZoneSDO.getCode());
                    forecastOrderLineBO.setShippingWarehouseName(cargoZoneSDO.getName());
                    forecastOrderLineBO.setShippingWarehouseId(cargoZoneSDO.getWarehouseId());
                    forecastOrderLineBO.setDeliveryFactoryCode(cargoZoneSDO.getSapFactoryCode());
                    forecastOrderLineBO.setStockCode(cargoZoneSDO.getWarehouseCode());

                    //货品校验
                    if (!scItemSDOMap.containsKey(forecastOrderLineBO.getProductCode())) {
                        forecastResponseDTO.setErrorCode("OC-04-001-01-16-009");
                        forecastResponseDTO.setMessage("物料编码不存在");
                        createResponseList.add(forecastResponseDTO);
                        orderSDOIterator.remove();
                        break detailLoopOuter;
                    }
                    ItemSearchAbilityDTO scItemSDO = scItemSDOMap.get(forecastOrderLineBO.getProductCode());
                    if (scItemSDO.getStatus() != 1) {
                        forecastResponseDTO.setErrorCode("OC-04-001-01-16-028");
                        forecastResponseDTO.setMessage("物料编码已禁用");
                        createResponseList.add(forecastResponseDTO);
                        orderSDOIterator.remove();
                        break detailLoopOuter;
                    }
                    forecastOrderLineBO.setProductId(scItemSDO.getScItemId());
                    forecastOrderLineBO.setProductName(scItemSDO.getTitle());
                    forecastOrderLineBO.setProductOutCode(scItemSDO.getOuterId());
                    forecastOrderLineBO.setItemBarCode(scItemSDO.getBarCode());
                    forecastOrderLineBO.setInnerProductName(scItemSDO.getTitle());
                    forecastOrderLineBO.setInventoryUnitName(scItemSDO.getUnit());
                    forecastOrderLineBO.setInventoryUnitCode(scItemSDO.getUnitCode());
                    forecastOrderLineBO.setCategoryCode(scItemSDO.getCategoryCode());
                    forecastOrderLineBO.setCategoryDesc(scItemSDO.getCategoryDesc());
                    forecastOrderLineBO.setCategoryChildCode(scItemSDO.getCategoryChildCode());
                    forecastOrderLineBO.setCategoryChildDesc(scItemSDO.getCategoryChildDesc());
                    forecastOrderLineBO.setItemCode(scItemSDO.getProductCode());
                    forecastOrderLineBO.setInnerProductCode(scItemSDO.getProductCode());

                    //销售单位校验
                    if (!itemUnitMap.containsKey(forecastOrderLineBO.getSaleUnitCode())) {
                        forecastResponseDTO.setErrorCode("OC-04-001-01-16-010");
                        forecastResponseDTO.setMessage("销售单位编码不存在");
                        createResponseList.add(forecastResponseDTO);
                        orderSDOIterator.remove();
                        break detailLoopOuter;
                    }
                    ItemUnitAbilityDTO saleUnit = itemUnitMap.get(forecastOrderLineBO.getSaleUnitCode());
                    forecastOrderLineBO.setSaleUnitName(saleUnit.getUnitName());

                    //库存单位校验
                    if (Objects.isNull(forecastOrderLineBO.getInventoryUnitCode()) || !itemUnitMap.containsKey(forecastOrderLineBO.getInventoryUnitCode())) {
                        forecastResponseDTO.setErrorCode("OC-04-001-01-16-011");
                        forecastResponseDTO.setMessage("基本单位不存在");
                        createResponseList.add(forecastResponseDTO);
                        orderSDOIterator.remove();
                        break detailLoopOuter;
                    }
                    ItemUnitAbilityDTO inventoryUnit = itemUnitMap.get(forecastOrderLineBO.getInventoryUnitCode());
                    forecastOrderLineBO.setInventoryUnitName(inventoryUnit.getUnitName());

                    //单位转换关系校验
                    if (!unitConvertMap.containsKey(forecastOrderLineBO.getProductCode() + "-" + forecastOrderLineBO.getSaleUnitCode())) {
                        forecastResponseDTO.setErrorCode("OC-04-001-01-16-010");
                        forecastResponseDTO.setMessage("销售单位编码不存在");
                        createResponseList.add(forecastResponseDTO);
                        orderSDOIterator.remove();
                        break detailLoopOuter;
                    }
                    Integer unitConvert = unitConvertMap.get(forecastOrderLineBO.getProductCode() + "-" + forecastOrderLineBO.getSaleUnitCode());
                    forecastOrderLineBO.setUnitConvert(String.valueOf(unitConvert));
                }

                //价格校验
                Map<String, PolicyPriceQueryRequest> linePriceMap = new HashMap<>();

                PolicyPriceMainRequest priceMainRequest = ForecastOrderBOToPriceOrderInfoConvertor.convert(forecastOrderBO);
                log.info("价格入参：" + JSON.toJSONString(priceMainRequest));
                List<PolicyPriceQueryRequest> policyPriceList = normalPriceQueryUtils.queryPolicyPrice(priceMainRequest);
                log.info("价格出参：" + JSON.toJSONString(policyPriceList));
                if (CollectionUtils.isNotEmpty(policyPriceList)) {
                    linePriceMap = policyPriceList.stream().collect(toMap(o -> o.getMaterialCode() + "-" + o.getSalesUnitCode(), Function.identity(), (v1, v2) -> v1));
                }

                //补货订单活动校验
                Boolean needCheckReplenishment = Boolean.FALSE;
                Map<String, ActivityInfoResponse> activityTermKeyMap = new HashMap<>();
                log.info("ForecastOrderBatchCreateAbility#invalidMainData#activity forecastOrderBO:{}", JSON.toJSONString(forecastOrderBO));
                if (forecastOrderBO.getOrderTypeCode().equals(ForecastOrderTypeEnum.REPLENISH_FORECAST.getCode())) {
                    String activityUniKey = String.format("%s_%s_%s_%s_%s",
                            forecastOrderBO.getSoldToPartyCode(),
                            forecastOrderBO.getSalesOrganizationCode(),
                            forecastOrderBO.getChannelCode(),
                            forecastOrderBO.getOrderType(),
                            forecastOrderBO.getShipToPartyCode());
                    if (!activityMap.containsKey(activityUniKey)) {
                        forecastResponseDTO.setErrorCode("OC-04-001-01-16-022");
                        forecastResponseDTO.setMessage("补货订单未命中补货活动");
                        createResponseList.add(forecastResponseDTO);
                        orderSDOIterator.remove();
                        continue;
                    }
                    needCheckReplenishment = Boolean.TRUE;
                    activityMap.get(activityUniKey).forEach(o -> {
                        String activityId = o.getActivityId();
                        o.getActivityTermList().forEach(x -> activityTermKeyMap.put(activityId + "-" + x.getActivityTermId(), o));
                    });
                }

                for (ForecastOrderLineBO forecastOrderLineBO : forecastOrderLineBOList) {
                    Long unitPrice = forecastOrderLineBO.getUnitPrice();
                    if (Objects.isNull(unitPrice)) {
                        String linePriceKey = forecastOrderLineBO.getProductCode() + "-" + forecastOrderLineBO.getSaleUnitCode();
                        PolicyPriceQueryRequest subOrderInfo = linePriceMap.get(linePriceKey);
                        if (!linePriceMap.containsKey(linePriceKey) || Objects.isNull(subOrderInfo)
                                || Objects.isNull(subOrderInfo.getUnitPrice()) || subOrderInfo.getUnitPrice() < 0L) {
                            forecastResponseDTO.setErrorCode("OC-04-001-01-16-013");
                            forecastResponseDTO.setMessage("价格不存在");
                            createResponseList.add(forecastResponseDTO);
                            orderSDOIterator.remove();
                            break detailLoopOuter;
                        }
                        unitPrice = subOrderInfo.getUnitPrice();
                    }
                    forecastOrderLineBO.setUnitPrice(unitPrice);
                    forecastOrderLineBO.setTotalFee(unitPrice * Long.parseLong(forecastOrderLineBO.getQuantity()));
                    if (needCheckReplenishment) {
                        String lineActivityTermKey = forecastOrderLineBO.getActivityCode() + "-" + forecastOrderLineBO.getActivityNumber();
                        if (!activityTermKeyMap.containsKey(lineActivityTermKey)) {
                            forecastResponseDTO.setErrorCode("OC-04-001-01-16-023");
                            forecastResponseDTO.setMessage("补货活动不匹配");
                            createResponseList.add(forecastResponseDTO);
                            orderSDOIterator.remove();
                            break detailLoopOuter;
                        }
                        ActivityInfoResponse activityInfoResponse = activityTermKeyMap.get(lineActivityTermKey);
                        forecastOrderLineBO.setActivityName(activityInfoResponse.getActivityNoteName());
                    }
                }

                log.info("预报订单校验通过: {}", JSON.toJSONString(forecastOrderBO));
            }
        }
    }
}
